#ifndef _DriverPD_H_
#define _DriverPD_H_


/* 拓展消息最大长度 */
#define ExMsgDataLenMax     28
/* 长度向上对齐 */
#define PD_ROUND_UP(x, n)   (((x) + (n) - 1) & (~((n) - 1)))


typedef struct
{
    uint16_t type               : 5;                /* 消息类型 */
    uint16_t PortDataRole       : 1;                /* 对于SOP消息代表接口的功能角色（0-UFP; 1-DFP）； 对于SOP’和SOP’’保留 */
    uint16_t version            : 2;                /* 此消息的当前版本（00-Rev1.0; 01-Rev2.0; 10-Rev3.0;） */
    uint16_t PortPowerRole      : 1;                /* 对于SOP信息，代表接口的供电角色（0-Sink; 1-Source）； 对于SOP’或SOP’’信息，代表此消息是接口发送的还是线缆发送的 */
    uint16_t ID                 : 3;                /* 消息ID,每发送一次，增加一次 */
    uint16_t number             : 3;                /* 后面数据的个数，每个数据是4字节了，对于非扩展包，此字段的值为0~7 */
    uint16_t extended           : 1;                /* 此消息是否为扩展类型 */
}PdMessHeadType;

typedef struct
{
    uint16_t dataSize           : 9;                /* 此字段应指示返回的数据块中总共有多少字节的数据，总计消息中的数据字节数不得超MaxExtendedMsgLen */
    uint16_t reserved           : 1;                /* shall be set to zero */
    uint16_t requestChunk       : 1;
    uint16_t chunkNumber        : 4;                /* Chunk Number字段指示返回的块的数目（只有当Chunked设置为 1 时，Chunked Number字段才在消息中有效） */
    uint16_t chunked            : 1;                /* 若Chunked位为1时，此字段为消息中填充到4字节边界的数据数量，包括作为第一 个数据对象一部分的扩展头；若Chunked位为0时，此字段作为保留字段。注意，在这种情况下，消息长度仅由扩展消息头中的数据大小字段确定。 */
}PdMessExHeadType;

typedef struct
{
    uint32_t command            : 5;                /* 0=Reserved, 1=Discover ldentity 2=Discover SVIDs 3=Discover Modes 4=Enter Mode 5=Exit Mode 6=Attention 7-15=Reserved 16...31=SVID Specifc Commands */
    uint32_t reserved1          : 1;                /* shall be set to zero */
    uint32_t commandType        : 2;                /* 00b=REQ 01b=ACK 10b=NAK 11b=BUSY */
    uint32_t objectPosition     : 3;                /* For the Enter Mode, Exit Mode, and Attention Commands */
    uint32_t minorVersion       : 2;                /*  */
    uint32_t majorVersion       : 2;                /*  */
    uint32_t type               : 1;                /* 0表示此为非结构化VDM；1表示此为结构化VDM */
    uint32_t VID                : 16;               /* USB-IF 分配给厂商的VID */
}PdVdmHeadType;

typedef struct
{
    uint32_t vendorID           : 16;               /* Manufacturers Shall set the Vend or lD field to the value of the Vendor lD assigned to them by USB-IF */
    uint32_t reserved           : 5;                /* shall be set to zero */
    uint32_t connectorType      : 2;                /* identifying it as either a USB Type-C receptacle or a USB Type-C plug. */
    uint32_t productTypeDFP     : 3;                /* see <USB PD Product Types[DFP] table>  */
    uint32_t modalOperation     : 1;                /* The Modal Operation Supported bit is used to indicate whether or the not the Product supports Modes */
    uint32_t productTypeUFP     : 3;                /* UFP or Cable Plug, see <USB PD Product Types[UFP] table>  */
    uint32_t capableAsDevice    : 1;                /* The Data Capable as a USB Device field is used to indicate whether or not the Port has a USB Device Capability. */
    uint32_t capableAsHost      : 1;                /* The Data Capable as a USB Host field is used to indicate whether or not the Port has a USB Host Capability. */
}PdIdHeadType;

typedef struct
{
    uint32_t speed              : 3;                /* 0=USB2.0 1=USB3.2Gen1 2=USB3.2Gen2 3=USB3.2Gen3 4=USB3.2Gen4 */
    uint32_t reserved2          : 2;                /* shall be set to zero */
    uint32_t currentCapab       : 2;                /* 1=3A 2=5A */
    uint32_t reserved1          : 2;                /* shall be set to zero */
    uint32_t maxVoltage         : 2;                /* Maximum Cable VBus Voltage. 0=20V 1=30V 2=40V 3=50V */
    uint32_t cableTermination   : 2;                /* 00b=VcoNN not required.Cable Plugs thatonly support Discover ldentityCommands Shall set these bits to 00b. 01b=VCONN required */
    uint32_t cableLatency       : 4;                /* the cable which can be used as an approximation for its length. */
    uint32_t EprCapable         : 1;                /* 0=Cable is notEPR Capable  1=Cable is EPR Capable */
    uint32_t captive            : 2;                /* 10b=USB Type-C 11b=Captive */
    uint32_t reserved           : 1;                /* shall be set to zero */
    uint32_t vdoVersion         : 3;                /* VDO 版本 */
    uint32_t softVersion        : 4;                /* 软件版本 */
    uint32_t hardVersion        : 4;                /* 硬件版本 */
}PdPassiveCableType;

/* https://blog.csdn.net/qq_43570266/article/details/134414268 */
typedef struct
{
    uint32_t maxCurrent         : 10;               /* Maximum Current in 10mA units */
    uint32_t voltage            : 10;               /* Voltage in 50mV units */
    uint32_t peakCurrent        : 2;                /* Peak Current */
    uint32_t reserved           : 1;                /* Reserved,shall be set to zero */
    uint32_t EprMode            : 1;                /* EPR Mode Capable */
    uint32_t UEMS               : 1;                /* Unchunked Extended Messages Supported */
    uint32_t dualRoleData       : 1;                /* Dual-Role Data */
    uint32_t usbComCapable      : 1;                /* USB Communications Capable */
    uint32_t unconPower         : 1;                /* Unconstrained Power */
    uint32_t suspendPower       : 1;                /* USB Suspend Power */
    uint32_t dualRolePower      : 1;                /* Dual-Role Power */
    uint32_t type               : 2;                /* Fixed Supply (must is 00) */
}PdSrcFixedType;

typedef struct
{
    uint32_t maxCurrent         : 10;               /* Maximum Current in 10mA units */
    uint32_t voltage            : 10;               /* Voltage in 50mV units */
    uint32_t reserved           : 3;                /* Reserved,shall be set to zero */
    uint32_t fastRoleSwap       : 2;                /* Fast Role Swap required USB Type-C Current(see also [USB Type-C2.3]) */
    uint32_t dualRoleData       : 1;                /* Dual-Role Data */
    uint32_t usbComCapable      : 1;                /* USB Communications Capable */
    uint32_t unconPower         : 1;                /* Unconstrained Power */
    uint32_t higherCapabi       : 1;                /* Higher Capability */
    uint32_t dualRolePower      : 1;                /* Dual-Role Power */
    uint32_t type               : 2;                /* Fixed Supply (must is 00) */
}PdSinkFixedType;

typedef struct
{
    uint32_t maxPower           : 10;               /* Maximum Allowable Power in 250mW units */
    uint32_t minVoltage         : 10;               /* Min Voltage in 50mV units */
    uint32_t maxVoltage         : 10;               /* Max Voltage in 50mV units */
    uint32_t type               : 2;                /* Battery Supply (must is 01) */
}PdSrcBatteryType;

typedef struct
{
    uint32_t operatPower        : 10;               /* Operational Power in 250mW units */
    uint32_t minVoltage         : 10;               /* Min Voltage in 50mV units */
    uint32_t maxVoltage         : 10;               /* Max Voltage in 50mV units */
    uint32_t type               : 2;                /* Battery Supply (must is 01) */
}PdSinkBatteryType;

typedef struct
{
    uint32_t maxCurrent         : 10;               /* Maximum Current in 10mA units */
    uint32_t minVoltage         : 10;               /* Min Voltage in 50mV units */
    uint32_t maxVoltage         : 10;               /* Max Voltage in 50mV units */
    uint32_t type               : 2;                /* Variable Supply (must is 10) */
}PdSrcVariableType;

typedef struct
{
    uint32_t operatCurrent      : 10;               /* Operational Current in 10mA units */
    uint32_t minVoltage         : 10;               /* Min Voltage in 50mV units */
    uint32_t maxVoltage         : 10;               /* Max Voltage in 50mV units */
    uint32_t type               : 2;                /* Variable Supply (must is 10) */
}PdSinkVariableType;

typedef struct
{
    uint32_t maxCurrent         : 7;                /* Maximum Current in 50mA units */
    uint32_t reserved0          : 1;                /* Reserved,shall be set to zero */
    uint32_t minVoltage         : 8;                /* Min Voltage in 100mV units */
    uint32_t reserved1          : 1;                /* Reserved,shall be set to zero */
    uint32_t maxVoltage         : 8;                /* Max Voltage in 100mV units */
    uint32_t reserved2          : 2;                /* Reserved,shall be set to zero */
    uint32_t powerLimited       : 1;                /* PPS Power Limited */
    uint32_t APDO               : 2;                /* SPR Programmbale Power Supply (must is 00) */
    uint32_t type               : 2;                /* SPR Programmable Supply (must is 11) */
}PdSrcSprProgramType;

typedef struct
{
    uint32_t inctements         : 8;                /* PDPin 1W increments */
    uint32_t minVoltage         : 8;                /* Min Voltage in 100mV units */
    uint32_t reserved           : 1;                /* Reserved,shall be set to zero */
    uint32_t maxVoltage         : 9;                /* Max Voltage in 100mV units */
    uint32_t peakCurrent        : 2;                /* Peak Current (see Table 6.15 "EPR AVS Power Source Peak Current Capability") */
    uint32_t APDO               : 2;                /* EPR Adjustable Voltage Supply (must is 01) */
    uint32_t type               : 2;                /* Augmented Power Data Object(APD0) (must is 11) */
}PdSrcEprAdjusType;

typedef struct
{
    uint32_t maxCurrent15V      : 10;               /* For 15V-20V range:Maximum Current in 10mA units equal to the Maximum Current field of the 20V Fixed Source PDO,set to 0 if the Maximum voltage in the SPR AVS range is 15V. */
    uint32_t maxCurrent9V       : 10;               /* For 9V-15V range:Maximum Current in 10mA units equal to the Maximum Current field of the 15V Fixed Source PDO */
    uint32_t reserved           : 6;                /* Reserved,shall be set to zero */
    uint32_t peakCurrent        : 2;                /* Peak Current (see Table 6.15 "EPR AVS Power Source Peak Current Capability") */
    uint32_t APDO               : 2;                /* SPR Adjustable Voltage Supply (must is 10) */
    uint32_t type               : 2;                /* Augmented Power Data Object(APD0) (must is 11) */
}PdSrcSprAdjusType;

typedef union
{
    /* SRC */
    PdSrcFixedType      fixed;                      /* Fixed Supply PDO - Source */
    PdSrcBatteryType    battery;                    /* Battery Supply PDO - Source */
    PdSrcVariableType   variable;                   /* Variable Supply (non-Battery) PDO - Source */
    PdSrcSprProgramType sprProgram;
    PdSrcEprAdjusType   eprAdjus;
    PdSrcSprAdjusType   sprAdjus;

    /* SINK */
    PdSinkFixedType     sinkFixed;                  /* Fixed Supply PDO - Sink */
    PdSinkBatteryType   sinkBattery;                /* Battery Supply PDO - Sink */
    PdSinkVariableType  sinkvariable;               /* Variable Supply (non-Battery) PDO - Sink */
}PdCapabiType;

/* 电源请求结构 */
typedef struct
{
    uint32_t  maxCurrent        : 10;               /* Maximum Operating Current in 10mA units */
    uint32_t  operatCurrent     : 10;               /* Operating current in 10mA units */
    uint32_t  reserved          : 2;                /* Reserved,shall be set to zero */
    uint32_t  EprMode           : 1;                /* EPR Mode Capable */
    uint32_t  UEMS              : 1;                /* Unchunked Extended Message Supported */
    uint32_t  noUsbSusped       : 1;                /* No USB Susped */
    uint32_t  usbComCapable     : 1;                /* USB Communications Capable */
    uint32_t  capabiMismatch    : 1;                /* Capability Mismatch */
    uint32_t  giveBackFlag      : 1;                /* Give Back Flag */
    uint32_t  objectPosition    : 4;                /* Object Position */
}PdRequestCapabiType;

typedef struct
{
    PdMessHeadType head;

    union
    {
        PdMessExHeadType headEx;
        uint8_t datas[ExMsgDataLenMax];
    };
}PdMessStdType;

typedef struct
{
    PdPassiveCableType passiveCable;                /* 线缆信息 */

    PdCapabiType srcCapabi[7];                      /* PD 源端支持的电源参数 */
    uint8_t srcCapabNum         : 3;                /* PD 源端支持的电源参数 数量 */

    uint8_t connected           : 2;                /* USB接入状态，bit0:CC1; bit1:CC2 */
    uint8_t version             : 2;                /* 00-Rev1.0; 01-Rev2.0; 10-Rev3.0; */
    uint8_t PortDataRole        : 1;                /* 0-UFP; 1-DFP */
    uint8_t PortPowerRole       : 1;                /* 0-Sink; 1-Source */
    uint8_t extended            : 1;                /* 1-支持拓展模式 */
    uint8_t ID                  : 3;                /* 消息ID,每发送一次，增加一次 */

    uint8_t status;                                 /* 状态（CC_STATUS）*/
    uint8_t statusLast;                             /* 状态（CC_STATUS）*/
    volatile uint32_t timeout;                      /* 状态起始时刻 */
}PdType;



int8_t cPdInit(void);
int8_t cPdResetHard(void);
int8_t cPdResetSoft(void);
int8_t cPdSrcInit(void);
int8_t cPdSinkInit(void);
void vPdCCSet(uint8_t ucFlags);
uint8_t ucPdCCDetect(void);
int8_t cPdRxMode(void);

int8_t cPdPackSend(uint8_t ucSop, uint8_t ucEx, uint8_t ucType, uint8_t ucID, void *pvDatas, int32_t iDataLength, int8_t cWaitCnt);
#define cPdPackControlSend(ucSop, ucType, ucID)                       cPdPackSend((ucSop), 0, (ucType), (ucID), NULL, 0, 0)
#define cPdPackDatasSend(ucSop, ucType, ucID, pvDatas, iDataLength)   cPdPackSend((ucSop), 0, (ucType), (ucID), (pvDatas), (iDataLength), 3)

int8_t cPdRequest(uint8_t ucIndex);

int8_t cPdPoll(void);
int8_t cPdMessRecive(PdMessStdType *ptypePdMess);


#endif
